/*  This is a modified version of the finite state machine from an ECE 485 assignment.  It models the Least Recently Used
logic of a 2-way set associative cache to determine what the order of access is in relation to the ways of a set, and
what the current least recently used way is, for purposes of eviction.

The inputs are:

access - When access goes high, the module assumes that an access is being made to the cache, and loads in the current
state bits from the cache set being accessed.  Depending on which line, or way, is being accessed, the module sets and
clears the appropriate bits in the current state, and loads them into the next state output register.  The process that
is activated by access going high also evaluates the new next state to determine what the current Least Recently Used
line or way is, and loads a 2-bit, one-hot encoded number representing that line into the LRU output register.

line - This is a 2-bit number that passes the information from the cache concerning which line or way from the set is
being accessed during this cycle.  In the next level up where this module is being implemented, the line bits
must be set before access is asserted, or else the output data will be invalid.

curstate - This is a 1-bit number that passes the current state from the cache to this module.  The current state is the
set of bits b(i,j) such that b = 1 if i>j or 0 if i<j.  For a 2 way cache only a single bit is need, b(0,1).

The outputs are:

data_valid - This is a single bit flag that is asserted when the nextstate and LRU output data are valid, i.e. not in the
process of being determined in the case statements.  When the case statement starts after access is asserted, the data_valid
output goes to 0, and is set back to 1 when the case statements are done.

nextstate - This is a 1-bit number that passes the new state from this module back to the cache.  It is the same data that
is passed in as curstate, but modified by setting or clearing the appropriate bits for the access that was made during this
cycle.  When data_valid is equal to 1, the data on this output is assumed to be valid and current for the set that it was
calculated for.

LRU - This is a 1-bit number that indicates which way or line in the set currently being accessed is the least recently used.  
Binary 0 corresponds to way 0, 1 to way 1.  When data_valid is equal to 1, the data on this output 
is assumed to be valid and current for the set that it was calculated for. */


module 2way_LRU (access, line, curstate, data_valid, nextstate, LRU);

input access, curstate;
input [1:0] line;
output data_valid, nextstate, LRU;

reg data_valid, nextstate, LRU, b0_1;

initial //Initial conditions of outputs 
begin
  b0_1 = 1'bx;
  data_valid = 1'b0;
  LRU = 1'bx;
  nextstate = 1'bx;
end

always @ (posedge access)
begin
  
  data_valid = 1'b0; //Data_valid set to 0 until new state and LRU are determined.
  b0_1 = curstate; //b(0,1) set from current state input
  LRU = 1'bx; //Clears the LRU output until it is recalculated

  casex (line)
  begin
  
    default : ;  //Any input besides the defined cases does nothing, invalid data.

    2'b00 : ;  //If no line is set, do nothing, invalid data.

    2'b01 : b0_1 = 1'b1;  //Line 0 set

    2'b10 : b0_1 = 1'b0; // Line 1 set

  end
  
  nextstate = b0_1; //Next state output register set with modified bit.
    
  casex (b0_1)
  begin
  
    default : ; //Do nothing if none of the conditions apply.

    1'b1 : LRU = 1'b0;  //Line 0 is the LRU.

    1'b0 : LRU = 1'b1;  //Line 1 is the LRU.

  end

  data_valid = 1'b1; //Data valid is set back to 1, because next state and LRU have been determined.

end

endmodule

